﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

public class FileHelper
{
    /// <summary>
    /// 安全创建文件，如过该文件夹不存在则创建文件夹
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static FileStream SafeCreate(string path)
    {
        path = path.Replace('\\', '/');
        int index = path.LastIndexOf('/');
        if (index > 0)
        {
            string dic = path.Substring(0, index);
            if (!Directory.Exists(dic))
            {
                Directory.CreateDirectory(dic);
                goto label;
            }
        }
        if (File.Exists(path))
            File.Delete(path);
        label:;
        return File.Create(path);
    }
    /// <summary>
    /// 创建文件夹，如果该文件夹不存在
    /// </summary>
    /// <param name="path"></param>
    public static void CreateFolder(string path)
    {
        path = path.Replace('\\', '/');
        int index = path.LastIndexOf('/');
        if (index > 0)
        {
            string dic = path.Substring(0, index);
            if (!Directory.Exists(dic))
            {
                Directory.CreateDirectory(dic);
            }
        }
    }
    public static void MoveFile(string a, string b)
    {
        CreateFolder(b);
        if (File.Exists(b))
            File.Delete(b);
        File.Copy(a, b);
    }
    public static string GetFolderName(string str)
    {
        string a = str.Replace('\\', '/');
        string[] ss = a.Split('/');
        return ss[ss.Length - 1];
    }
    public static string GetFolder(string str)
    {
        string a = str.Replace('\\', '/');
        int e = a.LastIndexOf('/');
        if (e < 1)
            return "";
        return a.Substring(0, e);
    }
    public static bool ContainFolder(string path, string name)
    {
        if (path == name)
            return true;
        int index = 0;
        for (int i = 0; i < path.Length; i++)
        {
            index = path.IndexOf(name, index);
            if (index < 0)
                return false;

            int nl = name.Length;
            if (index == 0)
            {
                if (path[nl] == '/')
                    return true;
            }
            else if (index + nl >= path.Length)
            {
                return true;
            }
            else
            {
                if (path[index - 1] == '/')
                    if (path[index + nl] == '/')
                        return true;
            }
            index += nl;
        }
        return false;
    }
    /// <summary>
    /// 获取文件名，无后缀
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static string GetFileName(string str)
    {
        string a = str.Replace('\\', '/');
        int s = a.LastIndexOf('/');
        if (s < 0)
            s = 0;
        else s++;
        int e = a.LastIndexOf('.');
        if (e < s)
            e = a.Length;
        int c = e - s;
        return a.Substring(s, c);
    }
    /// <summary>
    /// 获取文件名
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static string GetFileName2(string str)
    {
        string a = str.Replace('\\', '/');
        string[] ss = a.Split('/');
        return ss[ss.Length - 1];
    }
    /// <summary>
    /// 查询目录下所有符合条件的文件，包含子目录
    /// </summary>
    /// <param name="files">文件列表</param>
    /// <param name="dic">文件夹</param>
    public static void FindAllFiles(List<string> files, string dic)
    {
        string[] folder = Directory.GetDirectories(dic);
        if (folder != null)
            for (int i = 0; i < folder.Length; i++)
                FindAllFiles(files, folder[i]);
        string[] fs = Directory.GetFiles(dic);
        if (fs != null)
            files.AddRange(fs);
    }
    /// <summary>
    /// 查询目录下所有符合条件的文件，包含子目录
    /// </summary>
    /// <param name="files">文件列表</param>
    /// <param name="dic">文件夹</param>
    /// <param name="suffixName">过滤条件后缀名，格式"*.txt"</param>
    public static void FindAllFiles(List<string> files, string dic, string suffixName)
    {
        if (Directory.Exists(dic))
        {
            string[] fs = Directory.GetFiles(dic, suffixName, SearchOption.AllDirectories);
            if (fs != null)
                files.AddRange(fs);
        }
    }
    public static void FindAllFolder(List<string> folders, string dic, string filter)
    {
        if (Directory.Exists(dic))
        {
            FindFolder(folders, dic, filter);
        }
    }
    static void FindFolder(List<string> folders, string dic, string filter)
    {
        var dics = Directory.GetDirectories(dic);
        if (dics != null)
        {
            for (int i = 0; i < dics.Length; i++)
            {
                if (dics[i].LastIndexOf(filter) > -1)
                {
                    folders.Add(dics[i]);
                }
                else
                {
                    FindFolder(folders, dics[i], filter);
                }
            }
        }
    }

    public static void MoveFolder(string src, string des)
    {
        if (!Directory.Exists(des))
            Directory.CreateDirectory(des);
        var folders = Directory.GetDirectories(src);
        for (int i = 0; i < folders.Length; i++)
        {
            string sf = folders[i];
            string name = GetFileName(sf);
            string tar = des + "/" + name;
            MoveFolder(sf, tar);
        }
        var files = Directory.GetFiles(src);
        for (int i = 0; i < files.Length; i++)
        {
            string sf = files[i];
            string name = GetFileName2(sf);
            string tar = des + "/" + name;
            if (File.Exists(tar))
                File.Delete(tar);
            File.Move(sf, tar);
        }
    }
    public static void DeleteDirectory(string folder)
    {
        if (Directory.Exists(folder))
            DeleteDirectoryA(folder);
    }
    public static void DeleteDirectoryA(string folder)
    {
        var folders = Directory.GetDirectories(folder);
        if (folders != null)
            for (int i = 0; i < folders.Length; i++)
                DeleteDirectoryA(folders[i]);
        var files = Directory.GetFiles(folder);
        if (files != null)
            for (int i = 0; i < files.Length; i++)
                File.Delete(files[i]);
        Directory.Delete(folder);
    }
    // This method accepts two strings the represent two files to
    // compare. A return value of 0 indicates that the contents of the files
    // are the same. A return value of any other value indicates that the
    // files are not the same.
    public static bool FileEqual(string file1, string file2, byte[] buffer = null, byte[] buffer2 = null)
    {
        //int file1byte;
        //int file2byte;
        FileStream fs1;
        FileStream fs2;

        // Determine if the same file was referenced two times.
        if (file1 == file2)
        {
            // Return true to indicate that the files are the same.
            return true;
        }
        if (!File.Exists(file2))
            return false;

        // Open the two files.
        fs1 = new FileStream(file1, FileMode.Open);
        fs2 = new FileStream(file2, FileMode.Open);

        // Check the file sizes. If they are not the same, the files
        // are not the same.
        if (fs1.Length != fs2.Length)
        {
            // Close the file
            fs1.Close();
            fs2.Close();

            // Return false to indicate files are different
            return false;
        }

        if (buffer == null)
            buffer = new byte[1024];
        if (buffer2 == null)
            buffer2 = new byte[buffer.Length];
        int max = buffer.Length;
        if (max > buffer2.Length)
            max = buffer2.Length;
        // Read and compare a byte from each file until either a
        // non-matching set of bytes is found or until the end of
        // file1 is reached.
        int len = (int)fs1.Length;
        int c = 0;
        do
        {
            int t = fs1.Read(buffer, 0, max);
            fs2.Read(buffer2, 0, max);
            for (int i = 0; i < t; i++)
            {
                if (buffer[i] != buffer2[i])
                {
                    fs1.Close();
                    fs2.Close();
                    return false;
                }
            }
            c += t;
            // Read one byte from each file.
            //file1byte = fs1.ReadByte();
            //file2byte = fs2.ReadByte();
        }
        while (c < len);

        // Close the files.
        fs1.Close();
        fs2.Close();

        // Return the success of the comparison. "file1byte" is
        // equal to "file2byte" at this point only if the files are
        // the same.
        return true;
    }
}
